﻿#region License
/* SDL2# - C# Wrapper for SDL2
 *
 * Copyright (c) 2013-2016 Ethan Lee.
 *
 * This software is provided 'as-is', without any express or implied warranty.
 * In no event will the authors be held liable for any damages arising from
 * the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 * claim that you wrote the original software. If you use this software in a
 * product, an acknowledgment in the product documentation would be
 * appreciated but is not required.
 *
 * 2. Altered source versions must be plainly marked as such, and must not be
 * misrepresented as being the original software.
 *
 * 3. This notice may not be removed or altered from any source distribution.
 *
 * Ethan "flibitijibibo" Lee <flibitijibibo@flibitijibibo.com>
 *
 */
#endregion

#region Using Statements
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
#endregion

namespace SDL2
{
    public static class Win32API
    {
        [DllImport("kernel32")]
        public static extern IntPtr LoadLibraryA([MarshalAs(UnmanagedType.LPStr)] string fileName);
    }
    public static class UnixAPI
    {
        public const int RTLD_NOW = 2;

        [DllImport("dl", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr dlopen(byte[] filename, int flags);

        [DllImport("dl", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr dlerror();
    }

    public static partial class SDL
    {

        static SDL()
        {
            var is64 = IntPtr.Size == 8;
            var os = GetPlatform();
            Console.WriteLine("os = " + os);

            var startPath = System.IO.Path.GetDirectoryName(typeof(SDL).Assembly.Location);

            if (os == OSPlatform.Windows)
            {
                var product = "SDL2";
                var version = "2.0.10";
                var target = is64 ? "win32-x64" : "win32-x86";
                var path = "runtimes/" + product + "-" + version + "-" + target;
                var files = System.IO.Directory.GetFiles(path, "*.dll");
                foreach (var f in files)
                {
                    Win32API.LoadLibraryA(f);//只要loadlibrary了，就不可能找不到
                }
            }
            else if (os == OSPlatform.Linux)
            {
                //经测试netcore不能精确的识别linux 和 macos，都认为是Unix
                if (is64 == false)
                {
                    Console.WriteLine("only support 64 bit for OS:" + System.Environment.OSVersion.Platform);
                    return;
                }
                var so = "libSDL2.so";
                var targetSoPath = System.IO.Path.Combine(startPath, so);

                if (is64)
                {
                    //copy linux so to exe pos
                    var srcSoPath = System.IO.Path.Combine(startPath, "runtimes/SDL2-linux-x64", so);

                    System.IO.File.Delete(targetSoPath);
                    System.IO.File.Copy(srcSoPath, targetSoPath);

                    //try to load dll for test.
                    var file = SDL2.SDL.UTF8_ToNative(targetSoPath);
                    IntPtr p0 = UnixAPI.dlopen(file, UnixAPI.RTLD_NOW);
                    if (p0 == IntPtr.Zero)
                    {
                        IntPtr err = UnixAPI.dlerror();
                        Console.WriteLine("load " + so + " error" + SDL2.SDL.UTF8_ToManaged(err));
                    }
                }
                else
                {
                    Console.WriteLine("We do not have a " + so + " for " + os + " 32bit.You can install " + so + " yourself");
                }
            }
            else if (os == OSPlatform.OSX)
            {//copy macos dylib to exe pos
                var dylib = "libSDL2.dylib";
                var targetDylibPath = System.IO.Path.Combine(startPath, dylib);
                if (is64)
                {
                    var srcDylibPath = System.IO.Path.Combine(startPath, "runtimes/SDL2-osx-x64", dylib);
                    System.IO.File.Delete(targetDylibPath);
                    System.IO.File.Copy(srcDylibPath, targetDylibPath);

                    //try load
                    var file = SDL2.SDL.UTF8_ToNative(targetDylibPath);
                    IntPtr p0 = UnixAPI.dlopen(file, UnixAPI.RTLD_NOW);
                    if (p0 == IntPtr.Zero)
                    {
                        IntPtr err = UnixAPI.dlerror();
                        Console.WriteLine("load " + dylib + " error" + SDL2.SDL.UTF8_ToManaged(err));
                    }
                }
                else
                {
                    Console.WriteLine("We do not have a " + dylib + " for " + os + " 32bit.You can install " + dylib + " yourself");
                }
            }
            else
            {
                Console.WriteLine("NotSupport Platform = " + System.Environment.OSVersion.Platform + " is x64=" + is64);
            }

        }
        static OSPlatform GetPlatform()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                return OSPlatform.Linux;
            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                return OSPlatform.OSX;
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                return OSPlatform.Windows;
            throw new Exception("Not support OS.");
        }
    }
}
